import DatePicker from "components/antd-compatible/date-picker";
import React from 'react'
import {connect} from 'react-redux'
import {checkMenuDisabled, deepCopy, messages, queryCurrencyPrecision} from "share/common";
import {Button, Input, Select, Form, Row, Col, Icon, Spin, InputNumber,  message} from 'antd';
import corporatePaymentReportService from 'containers/corporate-payment-report/corporate-payment-report.service';

import Chooser from "components/chooser";
import Condition from 'components/condition'
import errorMessage from "share/errorMessage";
import moment from "moment";
import WrapFormItem from "components/wrap-form-item";
import ExpenseCard from "./create-expense-card"
import 'styles/corporate-payment-report/pay-info-detail.scss'
import PayInfoCustomFields from "../component/pay-info-custom-fields";
import AssociateContract from "./associate-contract";
import AddBankAccount from "../component/add-bank-account";
import { validation } from '../component/validation'

const FormItem = Form.Item;
const {TextArea} = Input;
const Option = Select.Option;
const {If, Else} = Condition;

class PayWithInvoice extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      loading: true,
      payInfoDetail: {},
      editMode: false,
      bankListOption: [],
      prepaymentApplyColumns: [
        {
          title: messages('finance-9.key8')/*对公支付单号*/,
          dataIndex: 'businessCode',
          width: 150
        }, {
          title: messages('common.currency')/*币种*/,
          dataIndex: 'currencyCode',
          width: 80
        }, {
          title: messages('finance-9.key9')/*核销金额*/,
          dataIndex: 'writeOffAmount',
          render: (value, record) => this.filterMoney(value, queryCurrencyPrecision(record.currencyCode)),
          width: 200
        }
      ],
      paymentMethodList: [],
      show: false,
      contract: [],
      associateAvailableAmount: 0, //可支付金额
      vendorInfo: {}
    };
  }

  componentWillMount() {
    const { paymentScheduleId, payInfoDetail } = this.props;
    let promiseList = [ this.getBankList(), this.handleGetPaymentMethod() ];
    paymentScheduleId && promiseList.push(this.getPayInfoDetail(paymentScheduleId));
    this.setState({ loading: true });
    Promise.all(promiseList).then(res => {
      let bankInfo = res[0].data || {};
      this.setState({
        loading: false,
        bankListOption: bankInfo.venBankAccountBeans,
        vendorInfo: {
          id: bankInfo.id,
          venNickname: bankInfo.venNickname,
          venderCode: bankInfo.venderCode,
          source: bankInfo.source,
          venderTypeId: bankInfo.venderTypeId,
          venderTypeName: bankInfo.venderTypeName,
        },
        paymentMethodList: res[1].data,
        payInfoDetail: res[2] ? res[2].data : {},
        associateAvailableAmount:  res[2] ? res[2].data.associateAvailableAmount : payInfoDetail.availableAmount || 0,
        contract: res[2] ? res[2].data.contractAssociatedDTOList : [],
        contractLineId:  (res[2] && res[2].data.contractAssociatedDTOList && res[2].data.contractAssociatedDTOList[0]) ?
          res[2].data.contractAssociatedDTOList[0].contractLineId : ''
      }, () => {
        if(!paymentScheduleId && payInfoDetail) {
          this.setState({
            payInfoDetail: Object.assign({}, deepCopy(payInfoDetail), {contractAssociatedDTOList: []})
          });
        }
      });
    }).catch(e => {
      this.setState({ loading: false });
      errorMessage(e.response);
    });
  }

  getPayInfoDetail = async paymentScheduleId => {
    return corporatePaymentReportService.getPayingInfoDetail(paymentScheduleId)
  };

  handleGetPaymentMethod = async () => {
    const { tenant: { tenantId }} = this.props;
    return corporatePaymentReportService.getApplicationPaymentMethod(tenantId)
  };

  getBankList = async () => {
    const { expenseInfo } = this.props;
    let params = {
      vendorInfoId: expenseInfo.corpSupplierId,
      status: 1001
    };
    return corporatePaymentReportService.getBanks(params);
  };

  handleSubmit = (e) => {
    const { payInfoDetail } = this.state;
    const { expenseInfo, isAuditEditable, operateMode } = this.props;
    this.props.form.validateFieldsAndScroll((err, values) => {
      if (!err) {
        let params = {
          paymentScheduleType: 1002, //前期发票行
          paymentScheduleId: operateMode === 'EDIT' ? payInfoDetail.id : null,
          planedAmount: values.planedAmount.planedAmount || 0,
          remark: values.remark,
          planedPaymentDate: values.planedPaymentDate,
          invoicePayeeInfoDTO: {
            bankAccount: values.accountNumber,
            payeeId: expenseInfo.corpSupplierId
          },
          expId: expenseInfo.id,
          paymentMethodDetailId: values.paymentMethodDetailId || payInfoDetail.paymentMethodDetailId,
          paymentMethodType: this.onGetPaymentMethod(values.paymentMethodDetailId || payInfoDetail.paymentMethodDetailId),
          invoiceViewDTO: payInfoDetail.invoiceViewDTO,
          prepaymentApplyDTOList: payInfoDetail.prepaymentApplyDTOList,
          contractAssociatedDTOList: payInfoDetail.contractAssociatedDTOList
        };
        !expenseInfo.contractHeaderId && delete params.contractAssociatedDTOList;
        validation(params).then(() => {
          this.setState({ loading: true });
          corporatePaymentReportService.savePayInfoDetail(params, isAuditEditable).then(res => {
            this.setState({ loading: false });
            this.props.close(true);
          }).catch(e => {
            this.setState({ loading: false });
            errorMessage(e.response)
          });
        }).catch(errorMessages => {
          if (errorMessages[0]) {
            errorMessages.length === 1 ? message.error(errorMessages) :
              message.error(errorMessages.map((item, index) => {
                return (<p style={{textAlign: 'left', margin: '5px 0 0'}}>{index + 1}: {item} </p>)
              }));
          }
        })
      }
    })
  };

  onChangeBankAccount = value => {
    const { bankListOption } = this.state;
    let selectedAccount = bankListOption.filter(i => i.bankAccount === value)[0];
    this.props.form.setFieldsValue({ accountName: selectedAccount.venBankNumberName });
  };

  onGetPaymentMethod = value => {
    const { paymentMethodList } = this.state;
    let selectedPaymentMethod = paymentMethodList.filter(i => i.id === value)[0];
    return selectedPaymentMethod.paymentMethodCategory;
  };

  onChangeContractLine = contract => {
    let { contractLineId, payInfoDetail } = this.state;
    //没有更改选择项时，不需要走下面的逻辑
    if (contract[0] && contract[0].contractLineId === contractLineId) { return; }
    contract[0] && contract.map(i => i.lineAvailableAmount = i.lineAvailableAmount || 0);
    this.setState({
      contractLineId: contract[0] && contract[0].contractLineId,
      payInfoDetail: Object.assign({}, payInfoDetail, { contractAssociatedDTOList: contract }),
      contract
    })
  };

  onCancel = () => {
    this.props.close();
  };

  setPlanedAmount = key => {
    const { payInfoDetail } = this.state;
    this.props.form.setFieldsValue({
      'planedAmount': {
        planedAmount: payInfoDetail[key === 'associateCorpBusinessCode' ? 'availableAmount' : 'planedAmount'] || 0
      }
    });
  };

  onRefreshPayInfoDetail = (value, key) => {
    const { payInfoDetail, associateAvailableAmount } = this.state;
    this.setState({
      show: false,
      associateAvailableAmount: key === 'associateCorpBusinessCode' ? value.availableAmount :
        associateAvailableAmount,
      payInfoDetail: Object.assign({}, payInfoDetail, {
          ...value,
          id: payInfoDetail.id,
          contractAssociatedDTOList: key === 'associateCorpBusinessCode' ? [] : (
            key === 'contractAssociatedDTOList' ? value.contractAssociatedDTOList :
              payInfoDetail.contractAssociatedDTOList),
          associateAvailableAmount: key === 'associateCorpBusinessCode' ? value.availableAmount :
            associateAvailableAmount,
        })
    }, () => key && this.setPlanedAmount(key))
  };

  formatBankNumber = value => {
    if(typeof value !== 'string') return value;
    return value.replace(/(^\d{4})(\d+)(\d{4}$)/, (target, $1, $2, $3) => {return $1 + $2.replace(/./g, '*') + $3})
  };

  payAllAvailable = () => {
    const { associateAvailableAmount } = this.state;
    this.props.form.setFieldsValue({ 'planedAmount':  { planedAmount: associateAvailableAmount } });
  };

  refreshBankOptions = (bankListOption, resetFields) => {
    this.setState({ bankListOption: bankListOption }, () => {
      this.props.form.setFieldsValue(resetFields);
    });
  };

  render() {
    const {loading, payInfoDetail, bankListOption, contractLineId, paymentMethodList, contract,
      editMode, associateAvailableAmount, vendorInfo } = this.state;
    const { operateMode, hasSupplierSetting, expenseInfo, entry, jobInfo,
      customFormPropertyMap, isAuditEditable
    } = this.props;
    const { getFieldDecorator } = this.props.form;
    let disabled = checkMenuDisabled();
    let editing = operateMode === 'CREATE' || (expenseInfo.status === 1001) || (isAuditEditable && editMode);
    let renderForm = i => (
      <div className='form-control'>
        <div className='form-label'>{PayInfoCustomFields(this)[i].label}</div>
        <div className='form-value'>{PayInfoCustomFields(this)[i].value(payInfoDetail, expenseInfo, paymentMethodList)}</div>
      </div>
    );
    return (
      <div className="pay-info-detail pay-with-previous-invoice">
        <If value={isAuditEditable && !editMode}>
          <a onClick={() => this.setState({ editMode: true })} className='edit-btn'>
            <Icon type="form" /> {messages('common.edit')/*编辑*/}
          </a>
        </If>
        <Spin spinning={loading}>
          <Form className="new-form">
            {
              editing ? (
                <div>
                  <h3 className='sub-title' style={{marginTop: 0}}>{messages('finance-9.key61')/*收款方信息*/}</h3>
                  <FormItem label={messages('finance-9.key10')/*收款方账号*/}>
                    {getFieldDecorator('accountNumber', {
                      initialValue: payInfoDetail.originAccountNumber,
                      rules: [{
                        required: true,
                        message: messages('common.please.select'),
                      }]
                    })(
                      <Select
                        className="edit-pay-info__select"
                        getPopupContainer={triggerNode => triggerNode.parentNode}
                        onChange={this.onChangeBankAccount}
                        placeholder={messages('common.please.select')}
                      >
                        {bankListOption.map(item => (
                          <Option
                            key={item.bankAccount}
                            style={{whiteSpace: 'normal'}}
                            title={`${item.bankAccount} ${item.bankName}`}
                          >
                            {this.formatBankNumber(item.bankAccount)} {item.bankName}
                          </Option>
                        ))}
                      </Select>
                    )}

                    <AddBankAccount
                      vendorInfo={vendorInfo}
                      expenseInfo={expenseInfo}
                      isAuditEditable={isAuditEditable}
                      hasSupplierSetting={hasSupplierSetting}
                      bankListOption={bankListOption}
                      refreshBankOptions={this.refreshBankOptions}
                    />
                  </FormItem>
                  <FormItem label={messages('finance-9.key11')/*收款方户名*/}>
                    {getFieldDecorator('accountName', {
                      initialValue: payInfoDetail.accountName,
                      rules: [{
                        required: true,
                        message: messages('common.please.input'),
                      }]
                    })(
                      <Input disabled={true} placeholder={messages('common.please.input')}/>
                    )}
                  </FormItem>
                  <h3 className='sub-title'>
                    <span className='form-title-label'>{messages('finance-9.key26')/*付款信息*/}</span>
                  </h3>
                  <FormItem label={messages('finance-9.key14')/*关联前期发票*/}>
                    {getFieldDecorator('associateCorpBusinessCode', {
                      initialValue: [operateMode === 'CREATE' ? {
                        businessCode: payInfoDetail.businessCode,
                        id: payInfoDetail.id
                      } : {
                        businessCode: payInfoDetail.associateCorpBusinessCode,
                        id: payInfoDetail.associatePaymentScheduleId
                      }],
                      rules: [{
                        required: true,
                        message: messages('common.name.is.required', { name: messages('finance-9.key14')/*关联前期发票*/ })
                      }]
                    })(
                      <Chooser
                        type="available_payment_info"
                        listExtraParams={{
                          expId: expenseInfo.id,
                          paymentScheduleId: payInfoDetail.id
                        }}
                        disabled={disabled}
                        labelKey="businessCode"
                        valueKey="id"
                        single={true}
                        hidePagination={true}
                        onChange={value => value[0] && this.onRefreshPayInfoDetail(value[0], 'associateCorpBusinessCode')}
                      />
                    )}
                  </FormItem>
                  <FormItem label={<span><Icon type="enter" className="rotate-icon" />{messages('finance-9.key69')/*费用详情*/}</span>}>
                    {getFieldDecorator('invoiceViewDTO', {
                      rules: [{
                        message: messages('common.name.is.required', { name: messages('finance-9.key69')/*费用详情*/ })
                      }]
                    })(
                      <ExpenseCard
                        editable={false}
                        applicantOID={expenseInfo.applicantOID}
                        expenseInfo={expenseInfo}
                        invoiceViewDTO={payInfoDetail.invoiceViewDTO}
                        onGetExpenseDetail={value => this.onRefreshPayInfoDetail({invoiceViewDTO: value})}
                        jobInfo={jobInfo}
                      />
                    )}
                  </FormItem>
                  {expenseInfo.contractHeaderId &&
                    <FormItem
                      label={messages('finance-9.key16')/*关联合同行*/}
                    >
                      {getFieldDecorator('contractAssociatedDTOList', {
                        initialValue: payInfoDetail.contractAssociatedDTOList || [],
                        rules: [{
                          required: true,
                          message: messages('common.name.is.required', { arg1: messages('finance-9.key16')/*关联合同行*/ })
                        }]
                      })(
                        contractLineId ? (
                          <AssociateContract
                            contract={contract || []}
                            editable={editing}
                            expenseInfo={expenseInfo}
                            onRefreshPayInfoDetail={value => this.onRefreshPayInfoDetail(value, 'contractAssociatedDTOList')}
                          />
                        ) : (
                          <Chooser
                            type="choose_contract"
                            listExtraParams={{
                              documentType: 'PUBLIC_REPORT',
                              companyOID: expenseInfo.docCompanyOID,
                              currency: expenseInfo.currencyCode,
                              contractHeaderId: expenseInfo.contractHeaderId,
                              applicantDepartmentOID: expenseInfo.applicantDepartmentOID,
                              partnerCategory: 'VENDOR',
                              corporateFlag: true
                            }}
                            disabled={
                              (!expenseInfo.contractHeaderId && expenseInfo.contractPosition === 'DOCUMENTS_HEAD') ||
                              entry === 'audit'
                            }
                            labelKey="contractNumber"
                            valueKey="contractLineId"
                            itemMap
                            onChange={this.onChangeContractLine}
                          />)
                      )}
                    </FormItem>
                  }
                  <FormItem
                    label={messages('finance-9.key17')/*本次支付金额*/}
                    extra={
                      <div>
                        {messages('finance-9.key97')/*可支付金额=费用未支付金额=*/}
                        {this.filterMoney(associateAvailableAmount, queryCurrencyPrecision(payInfoDetail.currencyCode), true)}
                        &nbsp;&nbsp;
                        {!contractLineId && <a onClick={this.payAllAvailable}>全部支付</a>}
                      </div>
                    }
                  >
                    {getFieldDecorator('planedAmount', {
                      initialValue: { planedAmount: payInfoDetail[operateMode === 'CREATE' ? 'availableAmount' : 'planedAmount'] || 0},
                      rules: [{
                        required: true
                      }]
                    })(
                      <WrapFormItem>
                        {(onChange, value) => (
                          <Row gutter={10}>
                            <Col span={12}>
                              <Select
                                disabled
                                value={expenseInfo.currencyCode}
                                placeholder='请选择'
                              >
                                <Option key={expenseInfo.currencyCode}>
                                  {expenseInfo.currencyCode + ' ' + expenseInfo.currencyCodeName}
                                </Option>
                              </Select>
                            </Col>
                            <Col span={12}>
                              <InputNumber
                                onChange={amount => onChange({planedAmount: amount})}
                                value={value.planedAmount || 0}
                                min={0}
                                max={associateAvailableAmount}
                                precision={queryCurrencyPrecision(expenseInfo.currencyCode)}
                                disabled={!!(payInfoDetail.contractAssociatedDTOList && payInfoDetail.contractAssociatedDTOList.length)}
                              />
                            </Col>
                          </Row>
                        )}
                      </WrapFormItem>
                    )}
                  </FormItem>
                  <FormItem label={messages('finance-9.key18')/*付款方式*/}>
                    {getFieldDecorator('paymentMethodDetailId', {
                      initialValue: payInfoDetail.paymentMethodDetailId || customFormPropertyMap['payment.method'],
                      rules: [{
                        required: true,
                        message: messages('common.please.select'),
                      }]
                    })(
                      <Select
                        getPopupContainer={triggerNode => triggerNode.parentNode}
                        placeholder={messages('common.please.select')}
                        key={'paymentMethod'}
                        onChange={this.onChangePaymentMethod}
                      >
                        {paymentMethodList.map(item => {
                          return <Option key={item.id}>{item.description}</Option>
                        })}
                      </Select>
                    )}
                  </FormItem>
                  <FormItem label={messages('finance-9.key19')/*计划付款日期*/}>
                    {getFieldDecorator('planedPaymentDate', {
                      initialValue: payInfoDetail.planedPaymentDate ? moment(payInfoDetail.planedPaymentDate) : null,
                      rules: [{
                        required: true,
                        message: messages('common.please.select'),
                      }]
                    })(
                      <DatePicker
                        disabledDate={date => date && date.valueOf() < moment().subtract(1, 'days').valueOf()}
                      />
                    )}
                  </FormItem>
                  <FormItem label={messages('common.remark')/*备注*/}>
                    {getFieldDecorator('remark', {
                      initialValue: payInfoDetail.remark
                    })(
                      <TextArea placeholder={messages('common.please.select')} />
                    )}
                  </FormItem>
                </div>
              ) : (
                <div>
                  <h3 className='sub-title' style={{marginTop: 0}}>{messages('finance-9.key61')/*收款方信息*/}</h3>
                  {['accountNumber', 'accountName'].map(i => renderForm(i))}
                  <h3 className='sub-title'>{messages('finance-9.key26')/*付款信息*/}</h3>
                  {['associateCorpBusinessCode', 'invoiceViewDTO', expenseInfo.contractHeaderId && 'contractAssociatedDTOList', 'planedAmount', 'paymentMethod', 'planedPaymentDate', 'remark']
                    .filter(i => !!i)
                    .map(i => renderForm(i))}
                </div>
              )
            }
          </Form>
        </Spin>
        <div className="slide-footer">
          {editing && (
            <Button type="primary" onClick={this.handleSubmit} loading={loading}>
              {messages("common.save")}
            </Button>)}
          <Button onClick={this.onCancel}>{messages("common.cancel")}</Button>
        </div>
      </div>
    )
  }
}

PayWithInvoice.contextTypes = {
  router: React.PropTypes.object
};

function mapStateToProps(state) {
  return {
    language: state.main.language,
    company: state.login.company,
    user: state.login.user,
    authPolicyAll: state.main.authPolicyAll,
    options: state.login.options,
    profile: state.login.profile,
    tenant: state.login.tenant
  }
}

const WrappedPayWithInvoice = Form.create()(PayWithInvoice);

export default connect(mapStateToProps)(WrappedPayWithInvoice);
